package com.tanhua.server.service;

import com.tanhua.commons.templates.OssTemplate;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.Comment;
import com.tanhua.domain.mongo.Publish;
import com.tanhua.domain.mongo.Visitor;
import com.tanhua.domain.vo.MovementsVo;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.domain.vo.TodayBestVo;
import com.tanhua.dubbo.api.*;
import com.tanhua.server.interceptor.UserHolder;
import com.tanhua.server.utils.RelativeDateFormat;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class MovementService {

    @Reference
    private PublishApi publishApi;

    @Reference
    private UserInfoApi userInfoApi;

    @Reference
    private CommentApi commentApi;

    @Reference
    private VisitorApi visitorApi;

    @Reference
    private RecommendUserApi recommendUserApi;

    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private MovementMQService movementMQService;

    //圈子发送动态功能
    public ResponseEntity<Object> publishMovement(Publish publish, MultipartFile[] imageContent) throws IOException {
        Long userId = UserHolder.getUserId();

        List<String> medias = new ArrayList<>();
        if(imageContent != null){
            for (MultipartFile multipartFile : imageContent) {
                String url = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
                medias.add(url);
            }
        }
        publish.setMedias(medias);
        publish.setUserId(userId);

        //【发送消息到mq中：要获取到动态id。所以在这里设置动态id，注意：api中要取消设置】
        publish.setId(ObjectId.get());
        //【发布动态，默认状态为未审核】
        publish.setState(0);

        publishApi.save(publish);

        //【发送消息到mq中，在tanhua-manage中，审核文本、图片】
        rocketMQTemplate.convertAndSend("tanhua-publish",publish.getId().toString());

        //发送消息到MQ，tanhua-commend进行消费
        movementMQService.publishMsg(publish.getId().toString());

        return ResponseEntity.ok(null);
    }

    //查看好友动态业务
    public ResponseEntity<Object> queryMovements(Integer page, Integer pagesize) {
        Long userId = UserHolder.getUserId();

        PageResult pageResult = publishApi.findByTimLine(page,pagesize,userId);

        List<Publish> items = (List<Publish>) pageResult.getItems();
        ArrayList<MovementsVo> movementsVos = new ArrayList<>();
        if(items != null){
            for (Publish item : items) {
                MovementsVo movementsVo = new MovementsVo();
                BeanUtils.copyProperties(item, movementsVo);
                UserInfo userInfo = userInfoApi.findById(item.getUserId());
                if(userInfo != null){
                    BeanUtils.copyProperties(userInfo,movementsVo);
                    if(userInfo.getTags() != null){
                        movementsVo.setTags(userInfo.getTags().split(","));
                    }
                }
                movementsVo.setId(item.getId().toString());
                if(item.getMedias() != null){
                    movementsVo.setImageContent(item.getMedias().toArray(new String[]{}));
                }
                movementsVo.setDistance("-10cm");
                movementsVo.setCreateDate(RelativeDateFormat.format(new Date(item.getCreated())));

                String key = "public_like_comment_" + userId + "_" +movementsVo.getId();
                if (redisTemplate.hasKey(key)){
                    movementsVo.setHasLiked(1);
                }else{
                    movementsVo.setHasLiked(0);
                }

                String love_key = "public_love_comment_" + userId + "_" + movementsVo.getId();
                if(redisTemplate.hasKey(love_key)){
                    movementsVo.setHasLoved(1);
                }else{
                    movementsVo.setHasLoved(0);
                }

                movementsVos.add(movementsVo);
            }
        }
        pageResult.setItems(movementsVos);
        return ResponseEntity.ok(pageResult);
    }

    //查看推荐动态业务
    public ResponseEntity<Object> recommend(Integer page, Integer pagesize) {
        Long userId = UserHolder.getUserId();

        PageResult pageResult = findByRecommend(page, pagesize);

        if (pageResult == null) {
            pageResult = publishApi.findByRecommend(page,pagesize,userId);
        }

        List<Publish> items = (List<Publish>)pageResult.getItems();
        ArrayList<MovementsVo> vos = new ArrayList<>();

        if (items != null){
            for (Publish item : items) {
                MovementsVo vo = new MovementsVo();
                BeanUtils.copyProperties(item, vo);
                UserInfo userInfo = userInfoApi.findById(item.getUserId());
                if(userInfo != null){
                    BeanUtils.copyProperties(userInfo, vo);
                    if (userInfo.getTags() != null){
                        vo.setTags(userInfo.getTags().split(","));
                    }
                }
                vo.setId(item.getId().toString());
                vo.setUserId(item.getUserId());
                if(item.getMedias() != null){
                    vo.setImageContent(item.getMedias().toArray(new String[]{}));
                }
                vo.setCreateDate(RelativeDateFormat.format(new Date(item.getCreated())));

                String love_key = "public_love_comment_" + userId + "_" + vo.getId();
                if(redisTemplate.hasKey(love_key)){
                    vo.setHasLoved(1);
                }else{
                    vo.setHasLoved(0);
                }

                String key = "public_like_comment_" + userId + "_" + vo.getId();
                if(redisTemplate.hasKey(key)){
                    vo.setHasLiked(1);
                }else{
                    vo.setHasLiked(0);
                }

                vo.setDistance("-10cm");
                vos.add(vo);
            }
        }

        pageResult.setItems(vos);
        return ResponseEntity.ok(pageResult);
    }

    //真正的推荐动态业务
    /**
     * 从redis查询推荐数据，查询第一页，每页5条
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult findByRecommend(Integer page,Integer pagesize){

        //凭借redis中的key
        String key = "QUANZI_PUBLISH_RECOMMEND_" + UserHolder.getUserId();

        //从redis中获取数据
        String value = redisTemplate.opsForValue().get(key);

        //判断数据是否存在，如果不存在，返回null
        if(StringUtils.isEmpty(value)){
            return null;
        }

        //如果数据存在，构造PageResult对象
        String[] pids = value.split(",");
        int startIndex = (page - 1) * pagesize;//计算本页的起始条数
        if(startIndex < pids.length){//起始条数小于数据总数
            int endIndex = startIndex + pagesize - 1;
            if(endIndex >= pids.length){
                endIndex = pids.length - 1;
            }
            ArrayList<Long> pidList = new ArrayList<>();//本业查询的所有动态的pid列表
            for (int i = startIndex;i <= endIndex; i++){
                pidList.add(Long.valueOf(pids[i]));
            }
            //本次分页的数据列表
            List<Publish> list = publishApi.findByPids(pidList);
            return new PageResult(page,pagesize,pids.length,list);
        }
        return null;
    }

    //查看我的动态业务
    public ResponseEntity<Object> all(Integer page, Integer pagesize, Long userId) {
        PageResult pageResult = publishApi.queryByUser(page,pagesize,userId);
        List<Publish> items = (List<Publish>)pageResult.getItems();
        ArrayList<MovementsVo> vos = new ArrayList<>();
        if(items != null){
            for (Publish item : items) {
                MovementsVo vo = new MovementsVo();
                BeanUtils.copyProperties(item, vo);
                UserInfo userInfo = userInfoApi.findById(userId);
                if(userInfo != null){
                    BeanUtils.copyProperties(userInfo, vo);
                    if(userInfo.getTags() != null){
                        vo.setTags(userInfo.getTags().split(","));
                    }
                }
                vo.setId(item.getId().toString());
                vo.setUserId(item.getUserId());
                if(item.getMedias() != null){
                    vo.setImageContent(item.getMedias().toArray(new String[]{}));
                }
                vo.setCreateDate(RelativeDateFormat.format(new Date(item.getCreated())));

                String key = "public_like_comment_" + userId + "_" + vo.getId();
                if(redisTemplate.hasKey(key)){
                    vo.setHasLiked(1);
                }else{
                    vo.setHasLiked(0);
                }

                String love_key = "public_love_comment_" + userId + vo.getId();
                if(redisTemplate.hasKey(love_key)){
                    vo.setHasLoved(1);
                }else{
                    vo.setHasLoved(0);
                }

                vo.setDistance("-10cm");
                vos.add(vo);
            }
        }
        pageResult.setItems(vos);
        return ResponseEntity.ok(pageResult);
    }

    //动态点赞功能业务
    public ResponseEntity<Object> likeComment(String publishId) throws NoSuchFieldException, IllegalAccessException {
        //获取登陆者的id
        Long userId = UserHolder.getUserId();
        //创建Comment，补全信息
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(1);
        comment.setPubType(1);
        comment.setUserId(userId);
        comment.setCreated(System.currentTimeMillis());


        //插入一个评论的记录，对点赞的朋友圈的点赞数+1，并且返回最新的点赞数
        long count = commentApi.save(comment);

        //设置一个标记，让手指头高亮
        String key = "public_like_comment_" + userId + "_" + publishId;
        redisTemplate.opsForValue().set(key, "1");
        //

        //发送消息，点赞
        movementMQService.likePublishMsg(publishId);

        return ResponseEntity.ok(count);
    }

    //动态取消点赞功能
    public ResponseEntity<Object> dislikeComment(String publishId) throws NoSuchFieldException, IllegalAccessException {
        Long userId = UserHolder.getUserId();

        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(1);
        comment.setUserId(userId);

        long count = commentApi.delete(comment);

        String key = "public_like_comment_" + userId + "_" + publishId;
        redisTemplate.delete(key);

        //发送消息，取消点赞
        movementMQService.dislikePublishMsg(publishId);

        return ResponseEntity.ok(count);
    }

    //动态喜欢功能
    public ResponseEntity<Object> love(String publishId) throws NoSuchFieldException, IllegalAccessException {
        Long userId = UserHolder.getUserId();

        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(3);
        comment.setPubType(1);
        comment.setUserId(userId);
        comment.setCreated(System.currentTimeMillis());

        long count = commentApi.save(comment);

        String key = "public_love_comment_" + userId + "_" + publishId;
        redisTemplate.opsForValue().set(key,"1");

        //发送消息，喜欢
        movementMQService.disLovePublishMsg(publishId);

        return ResponseEntity.ok(count);

    }

    //取消喜爱功能业务
    public ResponseEntity<Object> unlove(String publishId) throws NoSuchFieldException, IllegalAccessException {
        Long userId = UserHolder.getUserId();

        Comment comment = new Comment();
        comment.setCommentType(3);
        comment.setPublishId(new ObjectId(publishId));
        comment.setUserId(userId);

        long count = commentApi.delete(comment);

        String key = "public_love_comment_" + userId + "_" + publishId;
        redisTemplate.delete(key);

        //发送消息，取消喜欢
        movementMQService.disLovePublishMsg(publishId);

        return ResponseEntity.ok(count);

    }

    //查看单条动态业务
    public ResponseEntity<Object> singleMovement(String publishId) {
        Publish publish = publishApi.findById(publishId);

        MovementsVo vo = new MovementsVo();

        BeanUtils.copyProperties(publish, vo);
        UserInfo userInfo = userInfoApi.findById(publish.getUserId());
        if (userInfo != null) {
            BeanUtils.copyProperties(userInfo, vo);
            if(userInfo.getTags() != null){
                vo.setTags(userInfo.getTags().split(","));
            }
        }
        if(publish.getMedias() != null){
            vo.setImageContent(publish.getMedias().toArray(new String[]{}));
        }
        vo.setId(publish.getId().toString());
        vo.setUserId(publish.getUserId());
        vo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));
        vo.setDistance("-10cm");

        String like_key = "public_like_comment_" + userInfo + "_" + publishId;
        String love_key = "public_love_comment_" + userInfo + "_" + publishId;
        if(redisTemplate.hasKey(like_key)){
            vo.setHasLiked(1);
        }else{
            vo.setHasLiked(0);
        }
        if(redisTemplate.hasKey(love_key)){
            vo.setHasLoved(1);
        }else{
            vo.setHasLoved(0);
        }

        //发送消息，浏览动态
        movementMQService.queryPublishMsg(publishId);

        return ResponseEntity.ok(vo);
    }

    //有谁看过我业务
    public ResponseEntity<Object> queryVisitors() {
        //现根据当前登陆id查询访客表，获取访客信息
        String key = "visitors_time_" + UserHolder.getUserId();

        List<Visitor> list = null;

        if (!redisTemplate.hasKey(key)) {
            //第一次进入首页，显示最近5位访客
            list = visitorApi.queryByUid(UserHolder.getUserId());
        }else{
            //第二次进首页，显示上一次到本次之间的访客
            Long time = Long.parseLong(redisTemplate.opsForValue().get(key));
            list = visitorApi.queryByUid(UserHolder.getUserId(),time);
        }

        //记录本次访问的时间
        redisTemplate.opsForValue().set(key,System.currentTimeMillis()+"");

        //封装返回的结果
        ArrayList<TodayBestVo> vos = new ArrayList<>();
        if(list != null){
            for (Visitor visitor : list) {
                UserInfo userInfo = userInfoApi.findById(visitor.getVisitorUserId());
                TodayBestVo todayBestVo = new TodayBestVo();

                BeanUtils.copyProperties(userInfo,todayBestVo);
                todayBestVo.setId(userInfo.getId().intValue());
                if (userInfo.getTags() != null) {
                    todayBestVo.setTags(userInfo.getTags().split(","));
                }
                Long score = recommendUserApi.queryScore(visitor.getVisitorUserId(), visitor.getUserId());
                todayBestVo.setFateValue(score);

                vos.add(todayBestVo);
            }
        }
        return ResponseEntity.ok(vos);
    }
}
